using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using StudentManagement.Application.DTOs;
using StudentManagement.Application.Services;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace StudentManagement.API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class RoleController : ControllerBase
    {
        private readonly IRoleService _roleService;

        public RoleController(IRoleService roleService)
        {
            _roleService = roleService;
        }

        // GET: api/Role
        [HttpGet]
        [Authorize(Roles = "Admin")]
        public async Task<ActionResult<IEnumerable<RoleDTO>>> GetAllRoles()
        {
            var roles = await _roleService.GetAllRolesAsync();
            return Ok(roles);
        }

        // GET: api/Role/active
        [HttpGet("active")]
        [Authorize]
        public async Task<ActionResult<IEnumerable<RoleDTO>>> GetActiveRoles()
        {
            var roles = await _roleService.GetActiveRolesAsync();
            return Ok(roles);
        }

        // GET: api/Role/{id}
        [HttpGet("{id}")]
        [Authorize(Roles = "Admin")]
        public async Task<ActionResult<RoleDTO>> GetRoleById(int id)
        {
            var role = await _roleService.GetRoleByIdAsync(id);
            if (role == null)
            {
                return NotFound();
            }
            return Ok(role);
        }

        // GET: api/Role/by-name/{name}
        [HttpGet("by-name/{name}")]
        [Authorize(Roles = "Admin")]
        public async Task<ActionResult<RoleDTO>> GetRoleByName(string name)
        {
            var role = await _roleService.GetRoleByNameAsync(name);
            if (role == null)
            {
                return NotFound();
            }
            return Ok(role);
        }

        // GET: api/Role/search/{keyword}
        [HttpGet("search/{keyword}")]
        [Authorize(Roles = "Admin")]
        public async Task<ActionResult<IEnumerable<RoleDTO>>> SearchRoles(string keyword)
        {
            var roles = await _roleService.SearchRolesAsync(keyword);
            return Ok(roles);
        }

        // GET: api/Role/{id}/permissions
        [HttpGet("{id}/permissions")]
        [Authorize(Roles = "Admin")]
        public async Task<ActionResult<IEnumerable<PermissionDTO>>> GetPermissionsByRoleId(int id)
        {
            var permissions = await _roleService.GetPermissionsByRoleIdAsync(id);
            return Ok(permissions);
        }

        // POST: api/Role
        [HttpPost]
        [Authorize(Roles = "Admin")]
        public async Task<ActionResult<RoleDTO>> CreateRole([FromBody] RoleDTO roleDTO)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            try
            {
                var createdRole = await _roleService.CreateRoleAsync(roleDTO);
                return CreatedAtAction(nameof(GetRoleById), new { id = createdRole.Id }, createdRole);
            }
            catch (System.Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

        // PUT: api/Role/{id}
        [HttpPut("{id}")]
        [Authorize(Roles = "Admin")]
        public async Task<ActionResult<RoleDTO>> UpdateRole(int id, [FromBody] RoleDTO roleDTO)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            try
            {
                var updatedRole = await _roleService.UpdateRoleAsync(id, roleDTO);
                if (updatedRole == null)
                {
                    return NotFound();
                }
                return Ok(updatedRole);
            }
            catch (System.Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }

        // DELETE: api/Role/{id}
        [HttpDelete("{id}")]
        [Authorize(Roles = "Admin")]
        public async Task<ActionResult<bool>> DeleteRole(int id)
        {
            var result = await _roleService.DeleteRoleAsync(id);
            if (!result)
            {
                return NotFound();
            }
            return Ok(result);
        }

        // POST: api/Role/{roleId}/permissions/{permissionId}
        [HttpPost("{roleId}/permissions/{permissionId}")]
        [Authorize(Roles = "Admin")]
        public async Task<ActionResult<bool>> AddPermissionToRole(int roleId, int permissionId)
        {
            var result = await _roleService.AddPermissionToRoleAsync(roleId, permissionId);
            if (!result)
            {
                return NotFound();
            }
            return Ok(result);
        }

        // DELETE: api/Role/{roleId}/permissions/{permissionId}
        [HttpDelete("{roleId}/permissions/{permissionId}")]
        [Authorize(Roles = "Admin")]
        public async Task<ActionResult<bool>> RemovePermissionFromRole(int roleId, int permissionId)
        {
            var result = await _roleService.RemovePermissionFromRoleAsync(roleId, permissionId);
            if (!result)
            {
                return NotFound();
            }
            return Ok(result);
        }
    }
}